package com.dycong.common.database.mongoDB;

import lombok.extern.log4j.Log4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.javers.core.Javers;
import org.javers.core.diff.Change;
import org.javers.core.metamodel.type.EntityType;
import org.javers.repository.jql.JqlQuery;
import org.javers.repository.jql.QueryBuilder;
import org.javers.spring.auditable.AspectUtil;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Iterator;
import java.util.List;

/**
 * Created by Kenti on 2015/11/16.
 * <p>
 * 该类用来捕捉 javers audit 切面
 * 来实现更新的日志记录
 */
@Aspect
@Component
@Log4j
public class JaversCommitProcessor {

    /**
     * 当前修改的功能名
     */
    public static String currentUpdateMenu = "";

    /**
     * 此次更新是否做日志记录
     */
    public static boolean doLog = true;

    public static boolean autoClose = true;

    @Resource
    private Javers javers;

    /**
     * 使用around 意味如果更新方法执行异常 则不进行日志记录
     *
     * @param pjp
     */
    @Around("@annotation(org.javers.spring.annotation.JaversAuditable)")
    public void commitAdvice(ProceedingJoinPoint pjp) {
        try {
            pjp.proceed();
            if (doLog) {
                try {
                    Iterator var3 = AspectUtil.collectArguments(pjp).iterator();
                    if (var3.hasNext()) {
                        Object o = var3.next();
                        // 先提交数据
                        javers.commit(JaversUtil.user, o);
                        //处理
                        EntityType entityType = (EntityType) javers.getTypeMapping(o.getClass());
                        Object id = entityType.getIdProperty().get(o);
                        QueryBuilder queryBuilder = QueryBuilder.byInstanceId(id, o.getClass());
                        JqlQuery<?> jqlQuery = queryBuilder.build();
                        List<Change> changes = javers.findChanges(jqlQuery);
                        changes.sort(((o1, o2) -> -1 * o1.getCommitMetadata().get().getCommitDate().compareTo(o2.getCommitMetadata().get().getCommitDate())));
                        //处理得出的更改
                        if (changes.size() > 0) {
                            //每次更新完
                            JaversFactory.inMemoryRepository.commitDelete(changes.get(0).getAffectedGlobalId());
                            if (StringUtils.isNotEmpty(currentUpdateMenu)) {
//                                ContextUtil.getOperationLogService().doLog(currentUpdateMenu, o, changes.get(0).getAffectedLocalId() + "", changes, "更新");
                                log.info(currentUpdateMenu + "  =========  " + changes);
                            } else {
//                                ContextUtil.getOperationLogService().doLog(o, changes.get(0).getAffectedLocalId() + "", changes, "更新");
                                log.info("  ===============  " + changes);
                            }
                        }
                        return;
                    }
                } catch (Exception e) {
                    log.info("error do javers log ", e);
                }
            }
        } catch (Exception e) {
            log.info(e.toString());
        } catch (Throwable throwable) {
            log.info(throwable.toString());
        }
        if (autoClose) {
            doLog = true;
            currentUpdateMenu = "";
        }
    }
}
